package com.fzebu.fastboot.form;

import com.fzebu.fastboot.form.bean.FieldBean;
import com.fzebu.fastboot.form.parser.FieldDbTypeParser;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import weaver.conn.RecordSet;
import weaver.hrm.User;
import weaver.systeminfo.SystemEnv;

/**
 * @author Jack
 * @version 1.0.0
 * @create 2020/1/20 11:33
 */
public class FormClass {

    private static final int LANGUAGE = new User(1).getLanguage();

    private Builder builder;

    private FieldDbTypeParser parser;

    private FormClass(Builder builder) {
        this.builder = builder;
        this.parser = new FieldDbTypeParser();
    }

    public String getClassText() {
        if (builder.className == null) {
            return null;
        }
        String fieldText = this.buildFieldText();
        String classText = "import com.fzebu.fastboot.annotations.Alias;\n" +
                "import com.fzebu.fastboot.annotations.form.Number;\n" +
                "import com.fzebu.fastboot.annotations.form.Select;\n" +
                "import com.fzebu.fastboot.annotations.form.Browser;\n" +
                "import com.fzebu.fastboot.annotations.form.Text;\n" +
                "import com.fzebu.fastboot.annotations.form.Table;\n" +
                "import lombok.Getter;\n" +
                "import lombok.Setter;\n" +
                "import lombok.ToString;\n\n" +
                "@Setter\n" +
                "@Getter\n" +
                "@ToString\n" +
                "%s" +
                "public class %s {\n%s}";
        String tableText = "@Table(table=\"%s\",%s desc=\"%s\"%s)\n";

        String detailText = builder.detailId != null ? " detailId=" + builder.detailId + "," : "";
        builder.desc = builder.desc == null ? "" : builder.desc;

        String moduleText = (builder.modeId != null && builder.detailId == null)
                ? ", modeId=" + builder.modeId : "";

        tableText = String.format(tableText, builder.tableName, detailText, builder.desc, moduleText);
        return String.format(classText, tableText, builder.className, fieldText);
    }

    private String buildFieldText() {
        String sql = "select id, fieldlabel, fieldname, fielddbtype, fieldhtmltype, DETAILTABLE " +
                " from workflow_billfield where billid=?";
        RecordSet rs = new RecordSet();
        rs.executeQuery(sql, builder.formId);
        StringBuilder sb = new StringBuilder();
        FieldBean fieldBean;
        while (rs.next()) {
            String detailTable = rs.getString("DETAILTABLE");
            if (!checkForm(detailTable)) { continue; }
            fieldBean = new FieldBean();
            fieldBean.setId(rs.getString("id"));
            String fieldLabel = rs.getString("fieldlabel");
            String htmlLabelName = SystemEnv.getHtmlLabelName(Integer.parseInt(fieldLabel), LANGUAGE);
            fieldBean.setFieldLabel(htmlLabelName);
            fieldBean.setFieldName(rs.getString("fieldname"));
            fieldBean.setFieldDbType(rs.getString("fielddbtype"));
            fieldBean.setFieldHtmlType(rs.getString("fieldhtmltype"));
            sb.append(buildField(fieldBean));
        }
        return sb.toString();
    }

    private boolean checkForm(String detailTable) {
        if (builder.detailId != null) {
            // 明细表
            return StringUtils.equalsIgnoreCase(detailTable, builder.tableName);
        } else {
            // 主表
            return "".equals(detailTable);
        }
    }

    private String buildField(FieldBean fieldBean) {
        String text = "%s\n\tprivate %s %s;\n";
        parser.setFieldBean(fieldBean);
        String annotationText = parser.doParse();
        return String.format(text, annotationText, fieldBean.getFieldType(), fieldBean.getFieldName());
    }

    public static class Builder {

        private int formId;

        private String tableName;

        private String detailId;

        private String className;

        private String desc;

        private String modeId;

        public Builder tableName(String tableName) {
            String sql = "select ID formId from workflow_bill where tablename=?";
            RecordSet rs = new RecordSet();
            rs.executeQuery(sql, tableName);
            boolean isDetail = false;
            if (rs.getCounts() == 0) {
                sql = "select BILLID formId, orderid from workflow_billdetailtable where tablename=?";
                rs.executeQuery(sql, tableName);
                if (rs.getCounts() == 0) {
                    return this;
                } else {
                    isDetail = true;
                }
            }
            if (!rs.next()) { return this; }
            this.formId = rs.getInt("formId");
            this.className = "FormTable" + Math.abs(formId);
            if (isDetail) {
                // 明细表
                this.detailId = rs.getString("orderid");
                this.className += "MX" + this.detailId;
            }
            this.tableName = tableName;
            sql = "select ID, MODENAME formName, 1 as isModule from modeinfo where formid=?\n" +
                    "union all \n" +
                    " select ID, WORKFLOWNAME formName, 0 as isModule from workflow_base where formid=?";
            rs.executeQuery(sql, formId, formId);
            if (rs.next()) {
                this.desc = rs.getString("formName");
                if (BooleanUtils.toBoolean(rs.getInt("isModule"))) {
                    this.modeId = rs.getString("ID");
                }
            }
            return this;
        }

        public FormClass build() {
            if (formId == 0) {
                throw new IllegalStateException("formId == null");
            }
            return new FormClass(this);
        }
    }

}
